home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / sviluppo / svilupp2 / gmsppr10.lha / FormatString.c < prev    next >
C/C++ Source or Header  |  1996-08-23  |  16KB  |  639 lines

  1. #include <proto/exec.h>
  2. #include <proto/graphics.h>
  3. #include <proto/locale.h>
  4. #include <proto/utility.h>
  5.  
  6. #include "Global.h"
  7.  
  8. /************************************************************************/
  9.  
  10. struct String
  11. {
  12.   char *String;
  13.   ULONG Length;
  14.   ULONG Index;
  15. };
  16.  
  17. /************************************************************************/
  18.  
  19. #include "StaticSavedsAsmD0A3.h"
  20. #include "StaticSavedsAsmA0A1.h"
  21.  
  22. /************************************************************************/
  23. /*                                    */
  24. /* Interface RawDoFmt() to a Hook function                */
  25. /*                                    */
  26. /************************************************************************/
  27.  
  28. STATIC_SAVEDS_ASM_D0A3(void,Raw_Hook,char,c,struct Hook *,Hook)
  29.  
  30. {
  31.   CallHookPkt(Hook,NULL,(APTR)c);
  32. }
  33.  
  34.  
  35. /************************************************************************/
  36. /*                                    */
  37. /* Output a character into the self-extending string            */
  38. /*                                    */
  39. /************************************************************************/
  40.  
  41. STATIC_SAVEDS_ASM_A0A1(void,Hook_OutputChar_String,struct Hook *,Hook,char,c)
  42.  
  43. {
  44.   struct String *String;
  45.  
  46.   String=(struct String *)Hook->h_Data;
  47.   if (String->Index==String->Length)
  48.     {
  49.       char *NewString;
  50.  
  51.       if ((NewString=GS_MemoryAlloc(String->Length+128)))
  52.     {
  53.       if (String->String)
  54.         {
  55.           CopyMemQuick(String->String,NewString,String->Length);
  56.         }
  57.     }
  58.       GS_MemoryFree(String->String);
  59.       String->String=NewString;
  60.       String->Length+=128;
  61.     }
  62.   if (String->String)
  63.     {
  64.       String->String[String->Index++]=c;
  65.     }
  66. }
  67.  
  68. /************************************************************************/
  69. /*                                    */
  70. /* Render a character into a rastport                    */
  71. /*                                    */
  72. /************************************************************************/
  73.  
  74. STATIC_SAVEDS_ASM_A0A1(void,Hook_OutputChar_Draw,struct Hook *,Hook,char,c)
  75.  
  76. {
  77. #ifndef __GNUC__
  78.   char t;
  79.  
  80.   if ((t=c))
  81.     {
  82.       Text((struct RastPort *)Hook->h_Data,&t,1);
  83.     }
  84. #else
  85.   if (c)
  86.     {
  87.       Text((struct RastPort *)Hook->h_Data,&c,1);
  88.     }
  89. #endif
  90. }
  91.  
  92. /************************************************************************/
  93. /*                                    */
  94. /* Measure the width of a character                    */
  95. /*                                    */
  96. /************************************************************************/
  97.  
  98. STATIC_SAVEDS_ASM_A0A1(void,Hook_OutputChar_Width,struct Hook *,Hook,char,c)
  99.  
  100. {
  101. #ifndef __GNUC__
  102.   char t;
  103.  
  104.   if ((t=c))
  105.     {
  106.       Hook->h_SubEntry=(ULONG (*)())(((ULONG)Hook->h_SubEntry)+TextLength((struct RastPort *)Hook->h_Data,&t,1));
  107.     }
  108. #else
  109.   if (c)
  110.     {
  111.       Hook->h_SubEntry=(ULONG (*)())(((ULONG)Hook->h_SubEntry)+TextLength((struct RastPort *)Hook->h_Data,&c,1));
  112.     }
  113. #endif
  114. }
  115.  
  116. /****** gamesupport.library/GS_FormatString ******************************
  117. *
  118. *    NAME
  119. *    GS_FormatString -- sprintf() with unlimited string size
  120. *
  121. *    SYNOPSIS
  122. *    String = GS_FormatString(FormatString, Parameters, Length, Locale)
  123. *      d0                         a0            a1        a2      a3
  124. *
  125. *    char *GS_FormatString(const char *, const void *, ULONG *,
  126. *                          const struct Locale *);
  127. *
  128. *    FUNCTION
  129. *    This function works like sprintf(), but it creates it's own
  130. *    string. Therefore the length of the resulting string is not
  131. *    limited.
  132. *
  133. *    INPUTS
  134. *    FormatString - A format string for FormatString()
  135. *    Parameters   - The parameter list
  136. *    Length       - Optional pointer to an ULONG receiving strlen()
  137. *    Locale       - A pointer to a locale
  138. *
  139. *    NOTE
  140. *    If Locale==NULL or locale.library could not be opened,
  141. *    RawDoFmt() will be used to format the string.
  142. *
  143. *    RESULT
  144. *    String - the resulting string, or NULL if not enough memory.
  145. *             Call GS_MemoryFree() to free the string.
  146. *
  147. *************************************************************************/
  148.  
  149. SAVEDS_ASM_A0A1A2A3(char *,LibGS_FormatString,char *,Template,void *,Parameters,ULONG *,Length,struct Locale *,Locale)
  150.  
  151. {
  152.   struct String String;
  153.   struct Hook Hook;
  154.  
  155.   String.String=NULL;
  156.   String.Length=0;
  157.   String.Index=0;
  158.   Hook.h_Data=&String;
  159.   Hook.h_Entry=(ULONG (*)())Hook_OutputChar_String;
  160.   if (Locale!=NULL && LocaleBase!=NULL)
  161.     {
  162.       FormatString(Locale,Template,Parameters,&Hook);
  163.     }
  164.   else
  165.     {
  166.       RawDoFmt(Template,Parameters,Raw_Hook,&Hook);
  167.     }
  168.   if (Length && String.String)
  169.     {
  170.       *Length=String.Index-1;
  171.     }
  172.   return String.String;
  173. }
  174.  
  175. /************************************************************************/
  176. /*                                    */
  177. /* Format a date if locale.library is not available            */
  178. /*                                    */
  179. /************************************************************************/
  180.  
  181. void MyFormatDate(const char *Template, ULONG TimeStamp, struct Hook *Hook)
  182.  
  183. {
  184.   struct ClockData ClockData;
  185.  
  186.   Amiga2Date(TimeStamp,&ClockData);
  187.   if (Template!=NULL)
  188.     {
  189.       do
  190.     {
  191.       if (*Template=='%')
  192.         {
  193.           Template++;
  194.           switch (*Template)
  195.         {
  196.         case 'a':
  197.           {
  198.             char *t;
  199.  
  200.             t="SunMonTueWedThuFriSat"+3*ClockData.wday;
  201.             RawDoFmt("%3.3s",&t,Raw_Hook,Hook);
  202.           }
  203.           break;
  204.  
  205.         case 'A':
  206.           {
  207.             static char *Weekday[7]=
  208.               {
  209.             "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
  210.               };
  211.  
  212.             RawDoFmt("%s",&Weekday[ClockData.wday],Raw_Hook,Hook);
  213.           }
  214.           break;
  215.  
  216.         case 'b':
  217.         case 'h':
  218.           {
  219.             char *t;
  220.  
  221.             t="JanFebMarAprMayJunJulAugSepOctNovDec"+3*(ClockData.month-1);
  222.             RawDoFmt("%3.3s",&t,Raw_Hook,Hook);
  223.           }
  224.           break;
  225.  
  226.         case 'B':
  227.           {
  228.             static char *Month[12]=
  229.               {
  230.             "January", "February", "March", "April", "May", "June", "July",
  231.             "August","September", "October", "November", "December"
  232.               };
  233.  
  234.             RawDoFmt("%s",&Month[ClockData.month-1],Raw_Hook,Hook);
  235.           }
  236.           break;
  237.  
  238.         case 'c':
  239.           MyFormatDate("%a %b %d %H:%M:%S:%Y",TimeStamp,Hook);
  240.           break;
  241.  
  242.         case 'C':
  243.           MyFormatDate("%a %b %e %T %Z %Y",TimeStamp,Hook);
  244.           break;
  245.  
  246.         case 'd':
  247.           RawDoFmt("%02u",&ClockData.mday,Raw_Hook,Hook);
  248.           break;
  249.  
  250.         case 'D':
  251.         case 'x':
  252.           MyFormatDate("%m/%d/%y",TimeStamp,Hook);
  253.           break;
  254.  
  255.         case 'e':
  256.           RawDoFmt("%2u",&ClockData.mday,Raw_Hook,Hook);
  257.           break;
  258.  
  259.         case 'H':
  260.           RawDoFmt("%02u",&ClockData.hour,Raw_Hook,Hook);
  261.           break;
  262.  
  263.         case 'I':
  264.           {
  265.             UWORD Hour;
  266.  
  267.             Hour=ClockData.hour;
  268.             if (Hour>12)
  269.               {
  270.             Hour-=12;
  271.               }
  272.             else if (Hour==0)
  273.               {
  274.             Hour=12;
  275.               }
  276.             RawDoFmt("%02u",&Hour,Raw_Hook,Hook);
  277.           }
  278.           break;
  279.  
  280.         case 'm':
  281.           RawDoFmt("%02u",&ClockData.month,Raw_Hook,Hook);
  282.           break;
  283.  
  284.         case 'M':
  285.           RawDoFmt("%02u",&ClockData.min,Raw_Hook,Hook);
  286.           break;
  287.  
  288.         case 'n':
  289.           CallHookPkt(Hook,NULL,(APTR)'\n');
  290.           break;
  291.  
  292.         case 'p':
  293.           RawDoFmt((ClockData.hour<12 ? "AM" : "PM"),NULL,Raw_Hook,Hook);
  294.           break;
  295.  
  296.         case 'q':
  297.           RawDoFmt("%u",&ClockData.hour,Raw_Hook,Hook);
  298.           break;
  299.  
  300.         case 'Q':
  301.           {
  302.             UWORD Hour;
  303.  
  304.             Hour=ClockData.hour;
  305.             if (Hour>12)
  306.               {
  307.             Hour-=12;
  308.               }
  309.             else if (Hour==0)
  310.               {
  311.             Hour=12;
  312.               }
  313.             RawDoFmt("%u",&Hour,Raw_Hook,Hook);
  314.           }
  315.           break;
  316.  
  317.         case 'r':
  318.           MyFormatDate("%I:%M:%S %p",TimeStamp,Hook);
  319.           break;
  320.  
  321.         case 'R':
  322.           MyFormatDate("%H:%M",TimeStamp,Hook);
  323.           break;
  324.  
  325.         case 'S':
  326.           RawDoFmt("%02u",&ClockData.sec,Raw_Hook,Hook);
  327.           break;
  328.  
  329.         case 't':
  330.           CallHookPkt(Hook,NULL,(APTR)'\t');
  331.           break;
  332.  
  333.         case 'T':
  334.         case 'X':
  335.           MyFormatDate("%H:%M:%S",TimeStamp,Hook);
  336.           break;
  337.  
  338.         case 'w':
  339.           RawDoFmt("%u",&ClockData.wday,Raw_Hook,Hook);
  340.           break;
  341.  
  342.         case 'y':
  343.           {
  344.             UWORD Year;
  345.  
  346.             Year=ClockData.year%100;
  347.             RawDoFmt("%02u",&Year,Raw_Hook,Hook);
  348.           }
  349.           break;
  350.  
  351.         case 'Y':
  352.           RawDoFmt("%04u",&ClockData.year,Raw_Hook,Hook);
  353.           break;
  354.  
  355.         case '\0':
  356.           Template--;
  357.           /* fall through */
  358.  
  359.         default:
  360.           CallHookPkt(Hook,NULL,(APTR)*Template);
  361.         }
  362.         }
  363.       else
  364.         {
  365.           CallHookPkt(Hook,NULL,(APTR)*Template);
  366.         }
  367.       Template++;
  368.     }
  369.       while (*Template!='\0');
  370.     }
  371.   CallHookPkt(Hook,NULL,(APTR)'\0');
  372. }
  373.  
  374. /****** gamesupport.library/GS_FormatDate ********************************
  375. *
  376. *    NAME
  377. *    GS_FormatDate -- FormatDate() with unlimited string size
  378. *
  379. *    SYNOPSIS
  380. *    String = GS_FormatDate(Template, TimeStamp, Length, Locale)
  381. *      d0                      a0         d0       a1      a2
  382. *
  383. *    char *GS_FormatDate(const char *, ULONG, ULONG *,
  384. *                        const struct Locale *);
  385. *
  386. *    FUNCTION
  387. *    This function prints a date/time to a string.
  388. *
  389. *    INPUTS
  390. *    Locale    - A pointer to a locale
  391. *    Template  - A format string for FormatDate()
  392. *    TimeStamp - The date/time to output
  393. *
  394. *    NOTE
  395. *    If Locale==NULL or locale.library could not be opened,
  396. *    a builtin formatter will be used to format the date.
  397. *    The following commands are supported by this formatter:
  398. *    %a %A %b %B %c %C %d %D %e %h %H %I %m %M %n %p %q %Q
  399. *    %r %R %S %t %T %w %x %X %y %Y
  400. *
  401. *    RESULT
  402. *    String - the resulting string, or NULL if not enough memory.
  403. *             Call GS_MemoryFree() to free the string.
  404. *
  405. *************************************************************************/
  406.  
  407. SAVEDS_ASM_D0A0A1A2(char *,LibGS_FormatDate,ULONG,TimeStamp,char *,Template,ULONG *,Length,struct Locale *,Locale)
  408.  
  409. {
  410.   struct String String;
  411.   struct Hook Hook;
  412.  
  413.   String.String=NULL;
  414.   String.Length=0;
  415.   String.Index=0;
  416.   Hook.h_Data=&String;
  417.   Hook.h_Entry=(ULONG (*)())Hook_OutputChar_String;
  418.   if (Locale!=NULL && LocaleBase!=NULL)
  419.     {
  420.       struct DateStamp DateStamp;
  421.  
  422.       DateStamp.ds_Days=TimeStamp/(60*60*24);
  423.       TimeStamp=TimeStamp%(60*60*24);
  424.       DateStamp.ds_Minute=TimeStamp/60;
  425.       TimeStamp=TimeStamp%60;
  426.       DateStamp.ds_Tick=TimeStamp*TICKS_PER_SECOND;
  427.       FormatDate(Locale,Template,&DateStamp,&Hook);
  428.     }
  429.   else
  430.     {
  431.       MyFormatDate(Template,TimeStamp,&Hook);
  432.     }
  433.   if (Length && String.String)
  434.     {
  435.       *Length=String.Index-1;
  436.     }
  437.   return String.String;
  438. }
  439.  
  440. /****** gamesupport.library/GS_DrawString ********************************
  441. *
  442. *    NAME
  443. *    GS_DrawString -- draw a string into a rastport
  444. *
  445. *    SYNOPSIS
  446. *    GS_DrawString(Template, Parameters, RastPort, Locale)
  447. *                    a0          a1        a2        a3
  448. *
  449. *    void GS_DrawString(const char *, const void *, struct RastPort *,
  450. *                       const struct Locale *);
  451. *
  452. *    FUNCTION
  453. *    Draw a string into a rastport, using a formatting template.
  454. *
  455. *    INPUTS
  456. *    Template     - the formatting template for FormatString()
  457. *    Parameters   - the parameter list
  458. *    RastPort     - the destination rastport
  459. *    Locale       - the locale to use
  460. *
  461. *    NOTE
  462. *    If Locale==NULL or locale.library could not be opened,
  463. *    RawDoFmt() will be used to format the string.
  464. *
  465. *************************************************************************/
  466.  
  467. SAVEDS_ASM_A0A1A2A3(void,LibGS_DrawString,char *,Template,void *,Parameters,struct RastPort *,RastPort,struct Locale *,Locale)
  468.  
  469. {
  470.   struct Hook Hook;
  471.  
  472.   Hook.h_Data=RastPort;
  473.   Hook.h_Entry=(ULONG (*)())Hook_OutputChar_Draw;
  474.   if (Locale!=NULL && LocaleBase!=NULL)
  475.     {
  476.       FormatString(Locale,Template,Parameters,&Hook);
  477.     }
  478.   else
  479.     {
  480.       RawDoFmt(Template,Parameters,Raw_Hook,&Hook);
  481.     }
  482. }
  483.  
  484. /****** gamesupport.library/GS_DrawDate **********************************
  485. *
  486. *    NAME
  487. *    GS_DrawDate -- draw a date into a rastport
  488. *
  489. *    SYNOPSIS
  490. *    GS_DrawString(Template, TimeStamp, RastPort, Locale)
  491. *                    a0          d0        a1       a2
  492. *
  493. *    void GS_DrawDate(const char *, ULONG, struct RastPort *,
  494. *                     const struct Locale *);
  495. *
  496. *    FUNCTION
  497. *    Draw a date into a rastport.
  498. *
  499. *    INPUTS
  500. *    Template     - the formatting template for FormatDate()
  501. *    TimeStamp    - the time/date
  502. *    RastPort     - the destination rastport
  503. *    Locale       - the locale to use
  504. *
  505. *    NOTE
  506. *    If Locale==NULL or locale.library could not be opened,
  507. *    a builtin formatter will be used to format the date.
  508. *    The following commands are supported by this formatter:
  509. *    %a %A %b %B %c %C %d %D %e %h %H %I %m %M %n %p %q %Q
  510. *    %r %R %S %t %T %w %x %X %y %Y
  511. *
  512. *************************************************************************/
  513.  
  514. SAVEDS_ASM_D0A0A1A2(void,LibGS_DrawDate,ULONG,TimeStamp,char *,Template,struct RastPort *,RastPort,struct Locale *,Locale)
  515.  
  516. {
  517.   struct Hook Hook;
  518.  
  519.   Hook.h_Data=RastPort;
  520.   Hook.h_Entry=(ULONG (*)())Hook_OutputChar_Draw;
  521.   if (Locale!=NULL && LocaleBase!=NULL)
  522.     {
  523.       struct DateStamp DateStamp;
  524.  
  525.       DateStamp.ds_Days=TimeStamp/(60*60*24);
  526.       TimeStamp=TimeStamp%(60*60*24);
  527.       DateStamp.ds_Minute=TimeStamp/60;
  528.       TimeStamp=TimeStamp%60;
  529.       DateStamp.ds_Tick=TimeStamp*TICKS_PER_SECOND;
  530.       FormatDate(Locale,Template,&DateStamp,&Hook);
  531.     }
  532.   else
  533.     {
  534.       MyFormatDate(Template,TimeStamp,&Hook);
  535.     }
  536. }
  537.  
  538. /****** gamesupport.library/GS_StringWidth *******************************
  539. *
  540. *    NAME
  541. *    GS_StringWidth -- measure pixel width of a string
  542. *
  543. *    SYNOPSIS
  544. *    Width = GS_StringWidth(Template, Parameters, RastPort, Locale)
  545. *     d0                      a0          a1        a2        a3
  546. *
  547. *    WORD GS_StringWidth(const char *, const void *, struct RastPort *,
  548. *                        const struct Locale *);
  549. *
  550. *    FUNCTION
  551. *    Measure the width of the resulting string.
  552. *
  553. *    INPUTS
  554. *    Template     - the formatting template for FormatString()
  555. *    Parameters   - the parameter list
  556. *    RastPort     - the destination rastport
  557. *    Locale       - the locale to use
  558. *
  559. *    NOTE
  560. *    If Locale==NULL or locale.library could not be opened,
  561. *    RawDoFmt() will be used to format the string.
  562. *
  563. *************************************************************************/
  564.  
  565. SAVEDS_ASM_A0A1A2A3(WORD,LibGS_StringWidth,char *,Template,void *,Parameters,struct RastPort *,RastPort,struct Locale *,Locale)
  566.  
  567. {
  568.   struct Hook Hook;
  569.  
  570.   Hook.h_Data=RastPort;
  571.   Hook.h_Entry=(ULONG (*)())Hook_OutputChar_Width;
  572.   Hook.h_SubEntry=0;
  573.   if (Locale!=NULL && LocaleBase!=NULL)
  574.     {
  575.       FormatString(Locale,Template,Parameters,&Hook);
  576.     }
  577.   else
  578.     {
  579.       RawDoFmt(Template,Parameters,Raw_Hook,&Hook);
  580.     }
  581.   return (WORD)Hook.h_SubEntry;
  582. }
  583.  
  584. /****** gamesupport.library/GS_DateWidth *********************************
  585. *
  586. *    NAME
  587. *    GS_DateWidth -- measure pixel width of a date
  588. *
  589. *    SYNOPSIS
  590. *    Width = GS_DateWidth(Template, TimeStamp, RastPort, Locale)
  591. *     d0                    a0          d0        a1       a2
  592. *
  593. *    WORD GS_DateWidth(const char *, ULONG, struct RastPort *,
  594. *                      const struct Locale *);
  595. *
  596. *    FUNCTION
  597. *    Measure the pixel width of a date.
  598. *
  599. *    INPUTS
  600. *    Template     - the formatting template for FormatDate()
  601. *    TimeStamp    - the time/date
  602. *    RastPort     - the destination rastport
  603. *    Locale       - the locale to use
  604. *
  605. *    NOTE
  606. *    If Locale==NULL or locale.library could not be opened,
  607. *    a builtin formatter will be used to format the date.
  608. *    The following commands are supported by this formatter:
  609. *    %a %A %b %B %c %C %d %D %e %h %H %I %m %M %n %p %q %Q
  610. *    %r %R %S %t %T %w %x %X %y %Y
  611. *
  612. *************************************************************************/
  613.  
  614. SAVEDS_ASM_D0A0A1A2(WORD,LibGS_DateWidth,ULONG,TimeStamp,char *,Template,struct RastPort *,RastPort,struct Locale *,Locale)
  615.  
  616. {
  617.   struct Hook Hook;
  618.  
  619.   Hook.h_Data=RastPort;
  620.   Hook.h_Entry=(ULONG (*)())Hook_OutputChar_Width;
  621.   Hook.h_SubEntry=0;
  622.   if (Locale!=NULL && LocaleBase!=NULL)
  623.     {
  624.       struct DateStamp DateStamp;
  625.  
  626.       DateStamp.ds_Days=TimeStamp/(60*60*24);
  627.       TimeStamp=TimeStamp%(60*60*24);
  628.       DateStamp.ds_Minute=TimeStamp/60;
  629.       TimeStamp=TimeStamp%60;
  630.       DateStamp.ds_Tick=TimeStamp*TICKS_PER_SECOND;
  631.       FormatDate(Locale,Template,&DateStamp,&Hook);
  632.     }
  633.   else
  634.     {
  635.       MyFormatDate(Template,TimeStamp,&Hook);
  636.     }
  637.   return (WORD)Hook.h_SubEntry;
  638. }
  639.